package com.web.cloud.service.sm;

import com.web.cloud.constances.ModelConsts;
import com.web.cloud.constances.SessionConsts;
import com.web.cloud.dao.sm.SmOrgDao;
import com.web.cloud.exception.BusinessException;
import com.web.cloud.model.pub.tree.TreeNode;
import com.web.cloud.model.sm.SmOrg;
import com.web.cloud.service.pub.BaseService;
import com.web.cloud.utils.CommonConsts;
import com.web.cloud.utils.OrgInfoHolder;
import com.web.cloud.utils.TreeUtil;
import com.web.cloud.viewmodel.sm.SmOrgJson;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by liuhaiming on 2015/8/9.
 */
@Service
public class SmOrgService extends BaseService<SmOrg> {
    @Autowired
    private HttpSession session;

    private SmOrgDao getDao() {
        return (SmOrgDao)this.dao;
    }

    public String getModuleCode() {
        return ModelConsts.MODEL_SM;
    }

    public List<SmOrgJson> getOrgTreeRoot(boolean isEnableOnly) {
        int userType = (int) session.getAttribute(SessionConsts.SESSION_ATTRIBUTE_USER_TYPE);

        List<SmOrg> orgList = selectOrgTreeRoot(isEnableOnly, userType);

        List<SmOrgJson> result = new ArrayList<>();

        TreeNode<SmOrg> rootOrg = TreeUtil.buildTree(orgList);

        for (TreeNode<SmOrg> node : rootOrg.getChilds()) {
            result.add( chgNodeToRoleJson(node) );
        }

        return result;
    }

    private List<SmOrg> selectOrgTreeRoot(boolean isEnableOnly, int userType) {
        List<SmOrg> orgList;
        if ( isEnableOnly ) {
            orgList = selectEnableData(userType);
        } else {
            orgList = selectAllData(userType);
        }

        return orgList;
    }

    private List<SmOrg> selectEnableData(int userType) {
        List<SmOrg> orgList = null;
        if ( userType == CommonConsts.USER_TYPE_SYSTEM_ADMIN ) {
            orgList = getDao().selectEnableData();
        } else if ( userType == CommonConsts.USER_TYPE_ORG_ADMIN ) {
            orgList = selectEnableData(OrgInfoHolder.getOrgId());
        } else {
            orgList = new ArrayList<>();
        }

        return orgList;
    }

    private List<SmOrg> selectEnableData(String rootOrgId) {
        SmOrg rootOrg = get(rootOrgId);
        rootOrg.getIncode();

        return getDao().selectEnableOrgsByIncode(rootOrg.getIncode());
    }

    private List<SmOrg> selectAllData(int userType) {
        List<SmOrg> orgList = null;
        if ( userType == CommonConsts.USER_TYPE_SYSTEM_ADMIN ) {
            orgList = getDao().selectAll();
        } else if ( userType == CommonConsts.USER_TYPE_ORG_ADMIN ) {
            orgList = selectAllData(OrgInfoHolder.getOrgId());
        } else {
            orgList = new ArrayList<>();
        }

        return orgList;
    }

    private List<SmOrg> selectAllData(String rootOrgId) {
        SmOrg rootOrg = get(rootOrgId);

        return getDao().selectOrgsByIncode(rootOrg.getIncode());
    }


    private SmOrgJson chgNodeToRoleJson(TreeNode<SmOrg> node) {
        SmOrg org = node.getValue();
        SmOrgJson orgJson = new SmOrgJson(org);
        if (node.getChilds() != null) {

            List<SmOrgJson> children = new ArrayList<>();
            for (TreeNode<SmOrg> chld : node.getChilds()) {
                children.add( chgNodeToRoleJson(chld) );
            }

            if (children.size() > 0) {
                orgJson.setChildren( children );
            } else {
                orgJson.setIcon( SmOrgJson.ICON_LEAF );
            }
        }

        return orgJson;
    }

    public String createInncode(String parentId) {
        String incode = null;

        if ( !StringUtils.isEmpty(parentId) ) {
            SmOrg parentOrg = get(parentId);
            incode = parentOrg.getIncode() + createThislvl();
            long incodeCount = getDao().selectByInnerCode(incode);

            while ( incodeCount > 0 ) {
                incode = parentOrg.getIncode() + createThislvl();
                incodeCount = getDao().selectByInnerCode(incode);
            }
        } else {
            incode = createThislvl();
        }

        return incode;
    }

    private String createThislvl() {
        String codeLib = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random ran = new Random();

        String inncode = "";
        int LENGTH = 2;
        int tmpIdx = 0;
        for ( int idx = 0; idx < LENGTH; idx++ ) {
            tmpIdx = ran.nextInt(26);
            inncode += codeLib.substring( tmpIdx, tmpIdx+1 );
        }

        return inncode;
    }

    @Transactional( rollbackFor = {Exception.class} )
    public int saveOrgAndCreateDefaultRole(SmOrg smOrg) throws BusinessException {
        int result = super.save(smOrg);

        // create org's admin role when add org
//        smRoleService.createRoleByOrg(smOrg);

        return result;
    }
}